import com.mysql.cj.jdbc.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

//通过JDBC进行"插入数据"操作
public class QuickStart {
    public static void main(String[] args) throws SQLException {
        //1 创建"数据源"
        DataSource dataSource = new MysqlDataSource();//向上转型
        /*
        *要操作的数据库,数据是在哪里.在mysql中,需设定好mysql服务器的位置,要去访问数据库的名字,用户名和密码
        * MysqlDataSource这个类`就来自mysql的驱动包.
        * 上述过程就是 "数据库厂商写的代码和JDBC进行对接",也就相当于,让数据库厂商实现JDBC中提供的interface,进一步的实现其中约定好的抽象方法.
        *
        * */
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test_?characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong");//向下转型,转回来了~    设置url
        /*
        * URL 唯一资源定位符. 格式:协议的名称://IP地址:端口号/数据库名?参数=值&参数=值
        * mysql是一个"客户端-服务器"结构的程序,服务器是保存数据的本体.
        * 当前所写的jdbc代码,就相当于在写一个客户端.客户端就要通过网络访问到数据库服务器,来进一步的进行增删改查.
        * url描述了服务器/服务器上的资源在网络中的位置.
        *
        * */
        ((MysqlDataSource)dataSource).setUser("root");//设置用户名
        ((MysqlDataSource)dataSource).setPassword("");//设置密码

        //2 和数据库服务器进行连接
        Connection connection = dataSource.getConnection();//报错要抛异常;connection是java.sql包底下的

        //3 能够构造一个操作数据库的sql语句

        //用户输入信息
        System.out.println("请输入学号：");
        Scanner sc1 = new Scanner(System.in);
        int id = sc1.nextInt();
        System.out.println("请输入姓名：");
        Scanner sc2 = new Scanner(System.in);
        String name = sc2.next();

//      String sql = "insert into student values (11,'C++')";//第一种写法:要先确保数据库名和表名存在.    太死板
        //第二种写法:String sql = "insert into student values("+id+",'"+name+"')";//拼接字符串.        可读性差;不安全(可能引起sql注入攻击)
        //第三种写法:
        String sql = "insert into student values(?,?)";//用?占位符占个位置,需后续写代码做内容替换         推荐✔
        PreparedStatement preparedStatement = connection.prepareStatement(sql);//一个带有"预编译"的语句对象.内部会对sql进行解析校验
        preparedStatement.setInt(1,id);//从1开始的下标,对第一个内容进行替换.
        preparedStatement.setString(2,name);
        //4 执行sql
        int n = preparedStatement.executeUpdate();
        /*把解析好的语句发送给数据库服务器了,并且返回一个int类型,表这个操作影响了几行数据
        *执行这个方法,就会在内部给数据库服务器发送请求,请求中就包含了解析的sql.
        * 等待数据库服务器执行sql
        * 过一会,数据库执行完sql之后,返回响应
        * 这个方法再获取到响应,并把数据库服务器返回的结果通过返回值体现出来.
        *当然这个程序中可以构造多个sql,并且执行多次的~~
        */
        System.out.println("n="+n);

        //5 执行完毕 释放资源
        preparedStatement.close();
        connection.close();//主要释放语句对象和连接对象,DataSource不必释放.  释放顺序:先创建的后释放
    }
}
